#include <pthread.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <fcntl.h>
#include <functional>
#include <unistd.h>
#include <mutex>
#include <cstring>
#include <pthread.h>
#include "RingQueue.hpp"
#include "Thread.hpp"
#include "Thread.hpp"

using namespace std;
using namespace zzz;

// void productFunc(RingQueue<int> &r, string &name) // 生产线程函数——去放数据
// {
//     static int data = 1;
//     while (1)
//     {
//         r.product(data, name);
//         cout << "生产者外部>> " << name << "放上数据了:" << data++ << endl;
//     }
// }
// void consumerFunc(RingQueue<int> &r, string &name) // 消费线程函数——去拿数据
// {
//     int data;
//     while (1)
//     {
//         r.consume(&data, name);
//         cout << "消费者外部>> " << name << "拿到数据了:" << data << endl;
//         sleep(1);
//     }
// }
// void create_product(vector<Thread<RingQueue<int>>> &v, int num, RingQueue<int> &r) // 创建生产者线程
// {
//     for (int i = 0; i < num; i++)
//     {
//         string name = "product-" + to_string(i + 1);
//         v.emplace_back(productFunc, r, name);
//     }
// }
// void create_consumer(vector<Thread<RingQueue<int>>> &v, int num, RingQueue<int> &r) // 创建消费者线程
// {
//     for (int i = 0; i < num; i++)
//     {
//         string name = "consumer-" + to_string(i + 1);
//         v.emplace_back(consumerFunc, r, name);
//         // v.back().start(); //可以统一启动，因为这里的 back()会受主线程继续往 v 中增加而变动
//     }
// }

// int main()
// {
//     vector<Thread<RingQueue<int>>> v; // 用来管理线程的
//     RingQueue<int> ringqueue(10);     // 有一个环形队列，线程都对这个环形队列操作

//     create_product(v, 2, ringqueue);
//     create_consumer(v, 2, ringqueue);

//     for (auto &pthread : v)
//     {
//         cout << pthread.name() << " 开始了" << endl;
//         pthread.start();
//     }
//     for (auto &pthread : v)
//     {
//         pthread.join();
//     }

//     return 0;
// }

// 将数据变为某种任务函数
using Task = std::function<void()>;

using ringqueue_t = RingQueue<Task>; // 使用这个，就可以在这里直接变类型了，不用在各个地方都改一下

void Download()
{
    cout << "This is a download task!" << endl;
}
void productFunc(ringqueue_t &r, string &name)
{
    Task t(Download);
    while (1)
    {
        r.product(t, name);
        cout << "生产者外部>> " << name << "放上任务了！" << endl;
        sleep(1);
    }
}
void consumerFunc(ringqueue_t &r, string &name)
{
    Task t;
    while (1)
    {
        r.consume(&t, name);
        cout << "消费者外部>> " << name << "拿到任务了！" << endl;
        t(); // 执行任务
    }
}
void create_product(vector<Thread<ringqueue_t>> &v, int num, ringqueue_t &r) // 创建生产者线程
{
    for (int i = 0; i < num; i++)
    {
        string name = "product-" + to_string(i + 1);
        v.emplace_back(productFunc, r, name);
    }
}
void create_consumer(vector<Thread<ringqueue_t>> &v, int num, ringqueue_t &r) // 创建消费者线程
{
    for (int i = 0; i < num; i++)
    {
        string name = "consumer-" + to_string(i + 1);
        v.emplace_back(consumerFunc, r, name);
        // v.back().start(); //可以统一启动，因为这里的 back()会受主线程继续往 v 中增加而变动
    }
}

int main()
{
    vector<Thread<ringqueue_t>> v; // 用来管理线程的
    ringqueue_t ringqueue(10);     // 有一个环形队列，线程都对这个环形队列操作

    create_product(v, 1, ringqueue);
    create_consumer(v, 1, ringqueue);

    for (auto &pthread : v)
    {
        cout << pthread.name() << " 开始了" << endl;
        pthread.start();
    }
    for (auto &pthread : v)
    {
        pthread.join();
    }

    return 0;
}